package net.lab1024.sa.admin.module.business.roland.service;

import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import net.lab1024.sa.admin.module.business.roland.dao.RolandOrderDao;
import net.lab1024.sa.admin.module.business.roland.dao.RolandSeaDao;
import net.lab1024.sa.admin.module.business.roland.domain.entity.RolandSeaEntity;
import net.lab1024.sa.admin.module.business.roland.domain.form.*;
import net.lab1024.sa.admin.module.business.roland.domain.vo.RolandSeaVO;
import net.lab1024.sa.admin.module.business.roland.domain.vo.RolandSeatFrontVO;
import net.lab1024.sa.common.common.domain.PageResult;
import net.lab1024.sa.common.common.domain.ResponseDTO;
import net.lab1024.sa.common.common.util.SmartBeanUtil;
import net.lab1024.sa.common.common.util.SmartPageUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 座位信息表 Service
 *
 * @Author dragon
 * @Date 2023-12-11 13:29:10
 * @Copyright dragon
 */

@Service
public class RolandSeaService {
    private final String row1 = "1+";
    private final String row2 = "2+";

    @Autowired
    private RolandSeaDao rolandSeaDao;
    @Autowired
    private RolandOrderDao rolandOrderDao;

    /**
     * 分页查询
     *
     * @param queryForm
     * @return
     */
    public PageResult<RolandSeaVO> queryPage(RolandSeaQueryForm queryForm) {
        Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
        List<RolandSeaVO> list = rolandSeaDao.queryPage(page, queryForm);
        PageResult<RolandSeaVO> pageResult = SmartPageUtil.convert2PageResult(page, list);
        return pageResult;
    }

    /**
     * 添加
     */
    public ResponseDTO<String> add(RolandSeaAddForm addForm) {
        RolandSeaEntity rolandSeaEntity = SmartBeanUtil.copy(addForm, RolandSeaEntity.class);
        rolandSeaDao.insert(rolandSeaEntity);
        return ResponseDTO.ok();
    }

    /**
     * 更新
     *
     * @param updateForm
     * @return
     */
    public ResponseDTO<String> update(RolandSeaUpdateForm updateForm) {
        RolandSeaEntity rolandSeaEntity = SmartBeanUtil.copy(updateForm, RolandSeaEntity.class);
        rolandSeaDao.updateById(rolandSeaEntity);
        return ResponseDTO.ok();
    }

    /**
     * 批量删除
     *
     * @param idList
     * @return
     */
    public ResponseDTO<String> batchDelete(List<Integer> idList) {
        if (CollectionUtils.isEmpty(idList)) {
            return ResponseDTO.ok();
        }

        rolandSeaDao.deleteBatchIds(idList);
        return ResponseDTO.ok();
    }

    /**
     * 单个删除
     */
    public ResponseDTO<String> delete(Integer id) {
        if (null == id) {
            return ResponseDTO.ok();
        }

        rolandSeaDao.deleteById(id);
        return ResponseDTO.ok();
    }

    public ResponseDTO<String> updateAreaStatus(RolandSeaUpdateAreaStatusForm updateForm) {
        LambdaUpdateWrapper<RolandSeaEntity> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.eq(RolandSeaEntity::getFloor, updateForm.getFloor());
        updateWrapper.eq(RolandSeaEntity::getPosition, updateForm.getPosition());
        updateWrapper.set(RolandSeaEntity::getStatus, updateForm.getStatus());
        rolandSeaDao.update(null, updateWrapper);
        return ResponseDTO.ok();
    }

    public ResponseDTO<String> updateStatus(RolandSeaUpdateStatusForm updateForm) {
        LambdaUpdateWrapper<RolandSeaEntity> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.in(RolandSeaEntity::getId, updateForm.getIds());
        updateWrapper.set(RolandSeaEntity::getStatus, updateForm.getStatus());
        rolandSeaDao.update(null, updateWrapper);
        return ResponseDTO.ok();
    }

    public ResponseDTO<List<RolandSeatFrontVO>> seats() {
        LambdaQueryWrapper<RolandSeaEntity> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(RolandSeaEntity::getStatus, true);
        List<RolandSeaEntity> seats = rolandSeaDao.selectList(queryWrapper);

        // 已被占用的位置
        List<Integer> orderSeatIds = rolandOrderDao.selectOrderSeats();

        List<RolandSeaVO> row1List = new ArrayList<>(32);
        List<RolandSeaVO> row2List = new ArrayList<>(32);

        List<RolandSeaVO> floor1List = new ArrayList<>(800);
        List<RolandSeaVO> floor2List = new ArrayList<>(300);
        for (RolandSeaEntity v : seats) {
            RolandSeaVO vo = new RolandSeaVO();
            vo.setId(v.getId());
            vo.setFloor(v.getFloor());
            vo.setSeatRow(v.getSeatRow());
            vo.setSeatNo(v.getSeatNo());
            vo.setPosition(v.getPosition());
            vo.setStatus(v.getStatus());
            vo.setSelected(!v.getStatus() || orderSeatIds.contains(v.getId()));

            if (v.getSeatRow().equals(row1)) {
                row1List.add(vo);
            } else if (v.getSeatRow().equals(row2)) {
                row2List.add(vo);
            } else if (v.getFloor() == 1) {
                floor1List.add(vo);
            } else {
                floor2List.add(vo);
            }
        }


        List<RolandSeatFrontVO> result = new ArrayList<>(64);

        if (CollectionUtils.isNotEmpty(row1List)) {
            result.add(new RolandSeatFrontVO(1, row1, sort(row1List)));
        }
        if (CollectionUtils.isNotEmpty(row2List)) {
            result.add(new RolandSeatFrontVO(1, row2, sort(row2List)));
        }

        if (CollectionUtils.isNotEmpty(floor1List)) {
            TreeMap<Integer, List<RolandSeaVO>> floor1TreeMap = floor1List.stream()
                    .collect(Collectors.groupingBy(v -> Integer.valueOf(v.getSeatRow()), TreeMap::new, Collectors.toList()));
            for (Map.Entry<Integer, List<RolandSeaVO>> entry : floor1TreeMap.entrySet()) {
                result.add(new RolandSeatFrontVO(1, entry.getKey().toString(), sort(entry.getValue())));
            }
        }

        if (CollectionUtils.isNotEmpty(floor2List)) {
            TreeMap<Integer, List<RolandSeaVO>> floor2TreeMap = floor2List.stream()
                    .collect(Collectors.groupingBy(v -> Integer.valueOf(v.getSeatRow()), TreeMap::new, Collectors.toList()));
            for (Map.Entry<Integer, List<RolandSeaVO>> entry : floor2TreeMap.entrySet()) {
                result.add(new RolandSeatFrontVO(2, entry.getKey().toString(), sort(entry.getValue())));
            }
        }

        return ResponseDTO.ok(result);
    }

    private List<RolandSeaVO> sort(List<RolandSeaVO> row) {
        List<RolandSeaVO> odd = new ArrayList<>();
        List<RolandSeaVO> even = new ArrayList<>();
        for (RolandSeaVO vo : row) {
            if (NumberUtil.isEven(vo.getSeatNo())) {
                even.add(vo);
            } else {
                odd.add(vo);
            }
        }
        // 奇数左边从大到小
        odd.sort(Comparator.comparing(RolandSeaVO::getSeatNo, Comparator.reverseOrder()));
        // 偶数右边从小到大
        even.sort(Comparator.comparing(RolandSeaVO::getSeatNo));

        odd.addAll(even);
        return odd;
    }

}
